#pragma once

#include "common.hpp"
#include "Socket.hpp"



#define DEFAULT_BACKLOG 16
using io_service_t = std::function<void(std::shared_ptr<Socket>&, const Inet_Addr&)>;

class server_tcp : public no_copy
{
public:
    server_tcp(uint16_t port, const io_service_t& io_service)
        :_tcp_listen_socket_ptr(std::make_unique<TCP_Socket>())//父类指针指向子类, 实现多态
        ,_port(port)
        ,_running_tag(false)
        ,_io_service(io_service)
    {
        _tcp_listen_socket_ptr->create_listen_socket(_port, DEFAULT_BACKLOG);
    }

    void start()
    {
        _running_tag = true;
        while(_running_tag)
        {
            Inet_Addr client;
            std::shared_ptr<Socket> sock_p =_tcp_listen_socket_ptr->accept_socket(client);//tcp重写的accept_socket()返回了一个新的指向子类的父类指针(IO套接字)
            if(sock_p == nullptr)
                continue;

            //用多线程实现服务器: 让从线程去service, 并且将它分离, 主线程接着accept
            std::thread t(_io_service, std::ref(sock_p), std::ref(client)); //ref()传参, 线程拿到的才是引用, 
            t.detach();
        }
    }


private:
    std::unique_ptr<Socket> _tcp_listen_socket_ptr;//父类指针
    uint16_t _port;

    bool _running_tag;

    io_service_t _io_service;//由上层(protocol提供)传入, 交给从线程处理
};

